module cyclic_code_encode(
    input  wire        clk     ,
    input  wire        rst_n   ,
    input  wire        start   ,
    input  wire [11:0] data_in ,
    output reg         busy    ,
    output reg         done    ,
    output wire [22:0] data_out
);

    reg [ 3:0] cnt;
    reg [11:0] data_in_buf;
    reg [10:0] lfsr;

    wire feedback;

    assign feedback = (lfsr[10] ^ data_in_buf[11]);
    assign data_out = {data_in_buf, lfsr};

    always @(posedge clk, negedge rst_n) begin
        busy <= !rst_n ? 1'b0 : 
                start ? 1'b1 :
                done ? 1'b0 : 
                busy;

        done <= !rst_n ? 1'b0 :
                (cnt == 'd12) ? 1'b1 :
                1'b0;

        data_in_buf <= !rst_n ? 12'b0 : 
                        start ? data_in : 
                        (busy && !done) ? {data_in_buf[10:0], data_in_buf[11]} :
                        data_in_buf;
        
        cnt <= !rst_n ? 'd0 :
               (cnt == 'd12 || done) ? 'd0 :
               (start | busy) ? cnt + 'd1 :
               'd0;
    end

    // 生成多项式 g(x)=x^11+x^10+x^6+x^5+x^4+x^2+1
    always @(posedge clk, negedge rst_n) begin
        if (!rst_n) begin
            lfsr <= 11'b0;
        end else if (start) begin
            lfsr <= 11'b0;
        end else if (cnt >= 'd1 && cnt <= 'd12) begin
            lfsr[ 0] <= feedback          ;
            lfsr[ 1] <= lfsr[ 0]          ;
            lfsr[ 2] <= lfsr[ 1]^ feedback;
            lfsr[ 3] <= lfsr[ 2]          ;
            lfsr[ 4] <= lfsr[ 3]^ feedback;
            lfsr[ 5] <= lfsr[ 4]^ feedback;
            lfsr[ 6] <= lfsr[ 5]^ feedback;
            lfsr[ 7] <= lfsr[ 6]          ;
            lfsr[ 8] <= lfsr[ 7]          ;
            lfsr[ 9] <= lfsr[ 8]          ;
            lfsr[10] <= lfsr[ 9]^ feedback;
        end
    end
endmodule